package com.adk.backend.service.impl;

import com.adk.backend.common.PageResult;
import com.adk.backend.entity.LxTradeOrderList;
import com.adk.backend.mapper.TradeOrderMapper;
import com.adk.backend.service.TradeOrderService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.util.Calendar;

import java.util.List;
import java.util.Map;

/**
 * 贸易订单服务实现类
 */
@Slf4j
@Service
public class TradeOrderServiceImpl extends ServiceImpl<TradeOrderMapper, LxTradeOrderList> implements TradeOrderService {
    
    @Autowired
    private TradeOrderMapper tradeOrderMapper;
    
    @Autowired
    private com.adk.backend.mapper.TradeOrderStatusMapper tradeOrderStatusMapper;
    
    @Autowired
    private com.adk.backend.mapper.TradeBillListMapper tradeBillListMapper;
    
    @Autowired
    private com.adk.backend.mapper.TradeBillDetailsMapper tradeBillDetailsMapper;
    
    @Autowired
    private com.adk.backend.mapper.TradeFeeTypeMapper tradeFeeTypeMapper;
    
    @Autowired
    private com.adk.backend.mapper.BankListMapper bankListMapper;
    
    @Override
    public PageResult<Map<String, Object>> getTradeOrderList(Map<String, Object> params) {
        Integer pageNum = (Integer) params.getOrDefault("pageNum", 1);
        Integer pageSize = (Integer) params.getOrDefault("pageSize", 20);
        
        // 处理 ata 参数：PHP中使用字符串精确匹配 tol.ata='".$ata."'
        // ata 参数已经是 "YYYY-MM" 格式，直接使用字符串匹配
        
        // 处理 orderDate 参数：PHP中转换为 "Y-m" 格式，然后计算该月的开始和结束时间戳
        Object orderDateObj = params.get("orderDate");
        if (orderDateObj != null && StringUtils.hasText(orderDateObj.toString())) {
            try {
                java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM");
                java.util.Date date = sdf.parse(orderDateObj.toString());
                java.util.Calendar cal = java.util.Calendar.getInstance();
                cal.setTime(date);
                cal.set(Calendar.DAY_OF_MONTH, 1);
                cal.set(Calendar.HOUR_OF_DAY, 0);
                cal.set(Calendar.MINUTE, 0);
                cal.set(Calendar.SECOND, 0);
                int startInt = (int) (cal.getTimeInMillis() / 1000);
                
                cal.add(Calendar.MONTH, 1);
                cal.add(Calendar.SECOND, -1);
                int endInt = (int) (cal.getTimeInMillis() / 1000);
                
                params.put("orderDateStartInt", startInt);
                params.put("orderDateEndInt", endInt);
            } catch (Exception e) {
                log.warn("解析 orderDate 失败: {}", orderDateObj, e);
            }
        }
        
        // 计算偏移量
        Integer offset = (pageNum - 1) * pageSize;
        params.put("offset", offset);
        params.put("pageSize", pageSize);
        
        // 查询总数
        Long total = tradeOrderMapper.countTradeOrderList(params);
        
        // 查询列表
        List<Map<String, Object>> list = tradeOrderMapper.selectTradeOrderListWithInfo(params);
        
        PageResult<Map<String, Object>> result = new PageResult<>();
        result.setList(list);
        result.setTotal(total);
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        result.setTotalPages((int) Math.ceil((double) total / pageSize));
        
        return result;
    }
    
    @Override
    public LxTradeOrderList getTradeOrderById(Long id) {
        return tradeOrderMapper.selectById(id);
    }
    
    @Override
    public LxTradeOrderList getTradeOrderByOrderNo(String orderNo) {
        QueryWrapper<LxTradeOrderList> wrapper = new QueryWrapper<>();
        wrapper.eq("order_no", orderNo);
        return tradeOrderMapper.selectOne(wrapper);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public LxTradeOrderList createTradeOrder(LxTradeOrderList tradeOrder) {
        if (tradeOrder.getAddTime() == null) {
            tradeOrder.setAddTime((int) (System.currentTimeMillis() / 1000));
        }
        tradeOrderMapper.insert(tradeOrder);
        return tradeOrder;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTradeOrder(LxTradeOrderList tradeOrder) {
        if (tradeOrder.getEditTime() == null) {
            tradeOrder.setEditTime((int) (System.currentTimeMillis() / 1000));
        }
        return tradeOrderMapper.updateById(tradeOrder) > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTradeOrder(Long id) {
        return tradeOrderMapper.deleteById(id) > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTradeOrderStatus(Long id, Integer status) {
        LxTradeOrderList tradeOrder = tradeOrderMapper.selectById(id);
        if (tradeOrder == null) {
            return false;
        }
        tradeOrder.setStatus(status);
        if (tradeOrder.getEditTime() == null) {
            tradeOrder.setEditTime((int) (System.currentTimeMillis() / 1000));
        }
        return tradeOrderMapper.updateById(tradeOrder) > 0;
    }
    
    @Override
    public List<Map<String, Object>> getTradeOrderTracking(Long orderId) {
        // 贸易订单的跟踪信息可以通过订单跟踪服务获取
        // 这里返回一个空列表，实际应该调用OrderTrackingService
        return new java.util.ArrayList<>();
    }
    
    @Override
    public Map<String, Object> getTradeOrderStatusList(Long id) {
        Map<String, Object> result = new java.util.HashMap<>();
        
        // 查询订单号
        LxTradeOrderList tradeOrder = tradeOrderMapper.selectById(id);
        if (tradeOrder != null) {
            result.put("orderNo", tradeOrder.getOrderNo());
        }
        
        // 查询状态列表
        List<Map<String, Object>> statusList = tradeOrderStatusMapper.selectTradeOrderStatusWithUsername(id);
        result.put("statusList", statusList);
        
        return result;
    }
    
    @Override
    public Map<String, Object> getTradeOrderForDeclearCheck(Long id) {
        return tradeOrderMapper.selectTradeOrderForDeclearCheck(id);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDeclearCheck(Long id, Map<String, Object> params, Integer userId) {
        LxTradeOrderList tradeOrder = tradeOrderMapper.selectById(id);
        if (tradeOrder == null) {
            return false;
        }
        
        // 更新declearStatus相关字段
        if (params.containsKey("declearStatus")) {
            tradeOrder.setDeclearStatus((Integer) params.get("declearStatus"));
        }
        
        tradeOrder.setDeclearStatusAddTime((int) (System.currentTimeMillis() / 1000));
        tradeOrder.setDeclearStatusAddUid(userId);
        
        return tradeOrderMapper.updateById(tradeOrder) > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateBayan(Long id, Map<String, Object> params, Integer userId) {
        LxTradeOrderList tradeOrder = tradeOrderMapper.selectById(id);
        if (tradeOrder == null) {
            return false;
        }
        
        // 更新bayan字段
        if (params.containsKey("bayan")) {
            tradeOrder.setBayan((String) params.get("bayan"));
        }
        
        tradeOrder.setEditTime((int) (System.currentTimeMillis() / 1000));
        tradeOrder.setEditUid(userId);
        
        return tradeOrderMapper.updateById(tradeOrder) > 0;
    }
    
    @Override
    public Map<String, Object> getTradeFee(Long id) {
        Map<String, Object> result = new java.util.HashMap<>();
        
        // 查询订单信息
        LxTradeOrderList tradeOrder = tradeOrderMapper.selectById(id);
        if (tradeOrder == null) {
            return result;
        }
        
        result.put("id", tradeOrder.getId());
        result.put("orderNo", tradeOrder.getOrderNo());
        
        // 查询账单信息
        QueryWrapper<com.adk.backend.entity.LxTradeBillList> billWrapper = new QueryWrapper<>();
        billWrapper.eq("order_id", id);
        com.adk.backend.entity.LxTradeBillList bill = tradeBillListMapper.selectOne(billWrapper);
        if (bill != null) {
            result.put("billId", bill.getId());
            result.put("remarks", bill.getRemarks());
            result.put("totalAmount", bill.getTotalAmount());
        }
        
        // 查询账单明细列表
        List<Map<String, Object>> detailsList = tradeBillDetailsMapper.selectTradeBillDetailsWithInfo(id);
        result.put("detailsList", detailsList);
        
        // 查询费用类型列表
        QueryWrapper<com.adk.backend.entity.LxTradeFeeType> feeTypeWrapper = new QueryWrapper<>();
        feeTypeWrapper.orderByAsc("fee_name");
        List<com.adk.backend.entity.LxTradeFeeType> feeTypeList = tradeFeeTypeMapper.selectList(feeTypeWrapper);
        result.put("feeTypeList", feeTypeList);
        
        // 查询银行列表（type_id=2）
        QueryWrapper<com.adk.backend.entity.LxBankList> bankWrapper = new QueryWrapper<>();
        bankWrapper.eq("type_id", 2);
        bankWrapper.orderByDesc("id");
        List<com.adk.backend.entity.LxBankList> bankList = bankListMapper.selectList(bankWrapper);
        result.put("bankList", bankList);
        
        return result;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveTradeFee(Long id, Map<String, Object> params, Integer userId) {
        LxTradeOrderList tradeOrder = tradeOrderMapper.selectById(id);
        if (tradeOrder == null) {
            return false;
        }
        
        // 获取或创建账单
        Long billId = null;
        Object billIdObj = params.get("billId");
        if (billIdObj != null && !billIdObj.toString().isEmpty()) {
            billId = Long.parseLong(billIdObj.toString());
        }
        
        com.adk.backend.entity.LxTradeBillList bill;
        if (billId != null && billId > 0) {
            // 更新现有账单
            bill = tradeBillListMapper.selectById(billId);
            if (bill == null) {
                return false;
            }
            if (params.containsKey("remarks")) {
                bill.setRemarks((String) params.get("remarks"));
            }
            bill.setUpdateUid(userId);
            bill.setUpdateTime((int) (System.currentTimeMillis() / 1000));
            tradeBillListMapper.updateById(bill);
        } else {
            // 创建新账单
            bill = new com.adk.backend.entity.LxTradeBillList();
            bill.setOrderId(id);
            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
            bill.setBillDate(sdf.format(new java.util.Date()));
            bill.setBillDateInt((int) (System.currentTimeMillis() / 1000));
            if (params.containsKey("remarks")) {
                bill.setRemarks((String) params.get("remarks"));
            }
            bill.setAddUid(userId);
            bill.setAddTime((int) (System.currentTimeMillis() / 1000));
            tradeBillListMapper.insert(bill);
            billId = bill.getId();
        }
        
        // 处理账单明细
        java.math.BigDecimal totalAmount = java.math.BigDecimal.ZERO;
        boolean hasFee = false;
        
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> feeList = (List<Map<String, Object>>) params.get("feeList");
        if (feeList != null && !feeList.isEmpty()) {
            for (Map<String, Object> fee : feeList) {
                Object feeTypeObj = fee.get("feeType");
                if (feeTypeObj == null) {
                    continue;
                }
                Integer feeType = Integer.parseInt(feeTypeObj.toString());
                
                com.adk.backend.entity.LxTradeBillDetails detail;
                Object detailIdObj = fee.get("id");
                if (detailIdObj != null && !detailIdObj.toString().isEmpty()) {
                    Long detailId = Long.parseLong(detailIdObj.toString());
                    // 更新现有明细
                    detail = tradeBillDetailsMapper.selectById(detailId);
                    if (detail == null) {
                        continue;
                    }
                } else {
                    // 创建新明细
                    detail = new com.adk.backend.entity.LxTradeBillDetails();
                    detail.setBillId(billId);
                    detail.setOrderId(id);
                    detail.setAddUid(userId);
                    detail.setAddTime((int) (System.currentTimeMillis() / 1000));
                }
                
                detail.setFeeType(feeType);
                
                if (fee.get("qty") != null) {
                    detail.setQty(new java.math.BigDecimal(fee.get("qty").toString()));
                }
                if (fee.get("currencyId") != null) {
                    detail.setCurrencyId(Integer.parseInt(fee.get("currencyId").toString()));
                }
                if (fee.get("exchangeRate") != null) {
                    detail.setExchangeRate(new java.math.BigDecimal(fee.get("exchangeRate").toString()));
                }
                if (fee.get("price") != null) {
                    detail.setPrice(new java.math.BigDecimal(fee.get("price").toString()));
                }
                if (fee.get("paymentDate") != null) {
                    String paymentDate = fee.get("paymentDate").toString();
                    detail.setPaymentDate(paymentDate);
                    try {
                        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
                        java.util.Date date = sdf.parse(paymentDate);
                        detail.setPaymentDateInt((int) (date.getTime() / 1000));
                    } catch (Exception e) {
                        log.error("解析付款日期失败", e);
                    }
                }
                if (fee.get("bankId") != null && !fee.get("bankId").toString().isEmpty()) {
                    detail.setBankId(Long.parseLong(fee.get("bankId").toString()));
                }
                
                if (detailIdObj != null && !detailIdObj.toString().isEmpty()) {
                    detail.setUpdateUid(userId);
                    detail.setUpdateTime((int) (System.currentTimeMillis() / 1000));
                    tradeBillDetailsMapper.updateById(detail);
                } else {
                    tradeBillDetailsMapper.insert(detail);
                }
                
                // 计算总金额
                if (detail.getExchangeRate() != null && detail.getPrice() != null && detail.getQty() != null) {
                    java.math.BigDecimal amount = detail.getExchangeRate()
                            .multiply(detail.getPrice())
                            .multiply(detail.getQty());
                    totalAmount = totalAmount.add(amount);
                }
                hasFee = true;
            }
        }
        
        // 更新账单总金额
        bill.setTotalAmount(totalAmount);
        tradeBillListMapper.updateById(bill);
        
        // 更新订单财务状态
        Integer isDone = (Integer) params.get("isDone");
        if (isDone != null && isDone == 2) {
            // 已完成：状态17（已录入费用）
            tradeOrder.setFinanceStatus(17);
            updateTradeOrderStatusHistory(id, 17, "已录入费用");
        } else {
            if (hasFee) {
                // 录入中：状态16（录入中）
                tradeOrder.setFinanceStatus(16);
                updateTradeOrderStatusHistory(id, 16, "录入中");
            }
        }
        tradeOrderMapper.updateById(tradeOrder);
        
        return true;
    }
    
    /**
     * 更新贸易订单状态（内部辅助方法，用于记录状态历史）
     */
    private boolean updateTradeOrderStatusHistory(Long orderId, Integer status, String statusName) {
        try {
            com.adk.backend.entity.LxTradeOrderStatus orderStatus = new com.adk.backend.entity.LxTradeOrderStatus();
            orderStatus.setTolId(orderId);
            orderStatus.setStatusCode(status);
            orderStatus.setStatusName(statusName);
            
            int currentTime = (int) (System.currentTimeMillis() / 1000);
            orderStatus.setAddTime(currentTime);
            
            // 检查是否已存在该状态
            QueryWrapper<com.adk.backend.entity.LxTradeOrderStatus> wrapper = new QueryWrapper<>();
            wrapper.eq("tol_id", orderId);
            wrapper.eq("status_code", status);
            com.adk.backend.entity.LxTradeOrderStatus existing = tradeOrderStatusMapper.selectOne(wrapper);
            
            if (existing != null) {
                // 更新现有状态
                orderStatus.setId(existing.getId());
                tradeOrderStatusMapper.updateById(orderStatus);
            } else {
                // 插入新状态
                tradeOrderStatusMapper.insert(orderStatus);
            }
            return true;
        } catch (Exception e) {
            log.error("更新贸易订单状态历史失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean uploadCustom(Long id, MultipartFile[] files, Integer userId) {
        LxTradeOrderList tradeOrder = tradeOrderMapper.selectById(id);
        if (tradeOrder == null) {
            return false;
        }
        
        if (files == null || files.length == 0) {
            return false;
        }
        
        // 允许的文件类型
        String[] allowedTypes = {"pdf", "jpg", "jpeg", "png", "xlsx", "xls", "csv", "txt", "7z", "zip", "rar"};
        
        // 上传目录
        String uploadDir = "uploads/trade/declare_file";
        java.io.File dir = new java.io.File(uploadDir);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        
        // 上传文件
        StringBuilder declareFile = new StringBuilder();
        long timestamp = System.currentTimeMillis() / 1000;
        
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];
            if (file == null || file.isEmpty()) {
                continue;
            }
            
            try {
                String originalFilename = file.getOriginalFilename();
                if (originalFilename == null) {
                    continue;
                }
                
                // 获取文件扩展名
                String extension = "";
                if (originalFilename.contains(".")) {
                    extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
                }
                
                // 验证文件类型
                boolean isValidType = false;
                String lowerExtension = extension.toLowerCase();
                for (String type : allowedTypes) {
                    if (lowerExtension.equals(type)) {
                        isValidType = true;
                        break;
                    }
                }
                if (!isValidType) {
                    log.warn("不支持的文件类型: {}", extension);
                    continue;
                }
                
                // 生成文件名：userId-declare_file-timestamp序号.扩展名
                int fileNum = i + 1;
                String fileName = userId + "-declare_file-" + timestamp + "_" + fileNum + "." + extension;
                
                // 保存文件
                java.io.File targetFile = new java.io.File(dir, fileName);
                file.transferTo(targetFile);
                
                // 添加到文件列表（PHP格式：./uploads/trade/declare_file/文件名）
                if (declareFile.length() > 0) {
                    declareFile.append(",");
                }
                declareFile.append("./").append(uploadDir).append("/").append(fileName);
                
            } catch (Exception e) {
                log.error("上传文件失败: {}", file.getOriginalFilename(), e);
                // 继续处理其他文件
            }
        }
        
        if (declareFile.length() == 0) {
            return false;
        }
        
        // 更新订单
        tradeOrder.setDeclareFile(declareFile.toString());
        tradeOrder.setDeclearStatus(1);
        tradeOrder.setEditTime((int) (System.currentTimeMillis() / 1000));
        tradeOrder.setEditUid(userId);
        
        boolean success = tradeOrderMapper.updateById(tradeOrder) > 0;
        
        if (success) {
            // 记录操作日志（如果需要）
            log.info("用户 {} 上传了订单 {} 的报关文件", userId, id);
        }
        
        return success;
    }
}

